package tech.horgee.aoptest;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.yaml.snakeyaml.constructor.DuplicateKeyException;

/**
 * 全局异常处理
 *
 * @author haojun
 * @since 2020/3/18 20:22
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 捕捉自定义异常
     *
     * @param e 自定义异常
     * @return 统一返回体
     */
    @ExceptionHandler(MyException.class)
    public MyResult handler(MyException e) {
        return e.getResult();
    }

    /**
     * 捕捉参数校验异常
     *
     * @param e 参数校验异常
     * @return 统一返回体
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public MyResult handler(MethodArgumentNotValidException e) {
        StringBuilder builder = new StringBuilder();
        BindingResult bindingResult = e.getBindingResult();
        bindingResult.getAllErrors().forEach(i -> {
            FieldError fieldError = (FieldError) i;
            builder.append("【").append(fieldError.getField()).append("：");
            if (i.getDefaultMessage() != null) {
                builder.append(i.getDefaultMessage());
            } else {
                builder.append("参数不能为空");
            }
            builder.append("】");
        });
        return MyCode.DATA_VERIFY_ERROR.toResult(builder.toString());
    }

    /**
     * 捕捉其它异常
     *
     * @param e 其它异常
     * @return 统一返回体
     */
    @ExceptionHandler(Exception.class)
    public MyResult handler(Exception e) {
        MyResult result = MyResult.failure();
        if (e instanceof NoHandlerFoundException) {
            result.setCode(MyCode.NO_HANDLER_FOUND);
        } else if (e instanceof HttpMessageNotReadableException) {
            result.setCode(MyCode.MISSING_REQUEST_PARAMETERS);
        } else if (e instanceof HttpRequestMethodNotSupportedException) {
            result.setCode(MyCode.REQUEST_METHOD_NOT_SUPPORTED);
        } else if (e instanceof DuplicateKeyException) {
            result.setCode(MyCode.DUPLICATE_KEY);
        } else {
            result.setCode(MyCode.SERVER_ERROR);
        }
        log.error("「 ".concat(result.getMessage()).concat(" 」\n"), e);
        return result.setException(e.getLocalizedMessage());
    }
}
